/*
 * proxy_thread.h
 *
 *  Created on: 2013-12-19
 *      Author: lixingyi
 */

#ifndef PROXY_THREAD_H_
#define PROXY_THREAD_H_

#include <vector>
#include <string>
#include <map>
#include <memory>

#include <boost/lockfree/queue.hpp>

#include <regex.h>

#include "framework/thread.h"
#include "framework/circular_queue.h"
#include "framework/day_roll_logger.h"

#include "framework/day_roll_logger.h"

#include "libdrizzle-2.0/drizzle_client.h"
#include "libdrizzle-2.0/drizzle_server.h"



class DrizzleResponse
{
public:
    DrizzleResponse() { } ;
    
    ~DrizzleResponse() { drizzle_result_free(&m_result) ;} ;

   
    drizzle_result_st* result() { return &m_result ;} ;
private:
    drizzle_result_st m_result ;
    
} ;



class ProxyThread: public kingnet::simple_thread ,public std::enable_shared_from_this<ProxyThread>
{

public:
    ProxyThread();
    virtual ~ProxyThread();

public:
    /*
     *@brief should be called before thread start
     */
    void set_args(int fd) 
    { 
        m_client_fd = fd ; 
    } ;

    /*
     *@brief  state machine keep the spsc queue work correctly
     */
    bool push_response(DrizzleResponse* response)
    {
        bool ret = m_response_queue.push(response) ;
        if( ret == true ) pthread_cond_signal(&m_cond) ;
        return ret ;
    }


    std::shared_ptr<ProxyThread> get_ptr() { return this->shared_from_this() ; } ;

protected:
    virtual int on_init() ;
    virtual void on_fini() ;
    virtual void run_once() ;


    void on_timer() ;
    int on_response(DrizzleResponse* response) ;

    int get_thread_id(const char* sql) ;

    drizzle_return_t status_proxy();
    drizzle_return_t status_connect();
    drizzle_return_t status_read_auth();
    drizzle_return_t status_send_auth_result();

    drizzle_return_t status_read_query();
    drizzle_return_t status_wait_query_result() ;

private:
    pthread_cond_t m_cond ;
    pthread_mutex_t m_mutex ;

    int m_last_time ;
    int m_client_fd ;
    
    drizzle_st* m_drizzle ;
    drizzle_con_st* m_client ;
    DrizzleResponse* m_response ;
    drizzle_result_st m_result ;
    drizzle_row_t m_row ;
    int16_t m_field_index ;
    int8_t m_status ;
    boost::lockfree::queue<DrizzleResponse*,boost::lockfree::capacity<32> > m_response_queue ;
    regex_t m_re_role_id ;
    regex_t m_re_sid ;
    regex_t m_re_server_id ;


};

#endif /* DATA_THREAD_H_ */
